import 'dart:typed_data';

import 'package:flutter/material.dart';

// Element
abstract class WidgetElement {
  void accept(TranslationVisitor visitor);
}

// Visitor
abstract class TranslationVisitor {
  ({String text, String code}) translateText(String text);
  ({String text, String code}) translateVoice(Uint8List voice);
}

// ConcreteElement
class TextElement implements WidgetElement {
  String content;
  String code;
  TextElement(this.content, this.code);
  @override
  void accept(TranslationVisitor visitor) {
    var pair = visitor.translateText(content);
    content = pair.text;
    code = pair.code;
  }
}

class VoiceElement implements WidgetElement {
  final Uint8List voice;
  VoiceElement(this.voice);
  @override
  void accept(TranslationVisitor visitor) {
    visitor.translateVoice(voice);
  }
}
// ConcreteVisitor

class VoiceTranslationVisitor implements TranslationVisitor {
  @override
  ({String code, String text}) translateText(String text) {
    // TODO: implement translateText
    throw UnimplementedError();
  }

  @override
  ({String code, String text}) translateVoice(Uint8List voice) {
    // TODO: implement translateVoice
    throw UnimplementedError();
  }
}

class EnglishTranslationVisitor implements TranslationVisitor {
  @override
  ({String text, String code}) translateText(String text) {
    if (text == '欢迎') {
      return (text: 'Welcome', code: 'en');
    }
    return (text: text, code: 'zh');
  }

  @override
  ({String code, String text}) translateVoice(Uint8List voice) {
    // TODO: implement translateVoice
    throw UnimplementedError();
  }
}

class ChineseTranslationVisitor implements TranslationVisitor {
  @override
  ({String text, String code}) translateText(String text) {
    if (text == 'Welcome') {
      return (text: '欢迎', code: 'en');
    }
    return (text: text, code: 'zh');
  }

  @override
  ({String code, String text}) translateVoice(Uint8List voice) {
    // TODO: implement translateVoice
    throw UnimplementedError();
  }
}

// Client
class VisitorPatternPage extends StatefulWidget {
  const VisitorPatternPage({super.key});

  @override
  State<VisitorPatternPage> createState() => _VisitorPatternPageState();
}

class _VisitorPatternPageState extends State<VisitorPatternPage> {
  final TextElement _textElement = TextElement('Welcome', 'en');
  String _languageCode = 'en';
  TranslationVisitor get _visitor {
    switch (_languageCode) {
      case 'zh':
        return ChineseTranslationVisitor();
      default:
        return EnglishTranslationVisitor();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Visitor Pattern'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            DropdownButton(
                value: _languageCode,
                items: const [
                  DropdownMenuItem(
                    value: 'en',
                    child: Text('English'),
                  ),
                  DropdownMenuItem(
                    value: 'zh',
                    child: Text('中文'),
                  ),
                ],
                onChanged: (value) {
                  setState(() {
                    _languageCode = value!;
                    _textElement.accept(_visitor);
                  });
                }),
            Text(
              _textElement.content,
              style: const TextStyle(fontSize: 24),
            ),
          ],
        ),
      ),
    );
  }
}
